package nl.weeaboo.sh.io;

import static timon.common.xml.XmlUtil.getInt;
import static timon.common.xml.XmlUtil.getString;

import java.awt.Point;
import java.awt.Rectangle;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import nl.weeaboo.sh.model.CharaImageModel;
import nl.weeaboo.sh.model.ColCircle;
import nl.weeaboo.sh.model.DamageRect;

import org.xml.sax.SAXException;

import timon.common.Log;
import timon.common.xml.XmlElement;
import timon.common.xml.XmlReader;

public class CharaImageLoader extends XmlReader {

	private String imagePath;
	private Rectangle levelRect;
	
	public CharaImageLoader() {
	}

	//Functions
	public List<CharaImageModel> load(String path) throws SAXException, IOException {
		FileInputStream fin = new FileInputStream(path);
		try {
			return load(fin);
		} finally {
			fin.close();
		}
	}
	public List<CharaImageModel> load(InputStream in) throws SAXException, IOException {
		XmlElement root = super.read(in).getFirstElementChild();
		
		List<CharaImageModel> images = new ArrayList<CharaImageModel>();

		imagePath = getString(root, "imagePath");
		levelRect = parseRect(root.getChild("levelHitbox"));
		
		XmlElement spritesE = root.getChild("images");
		for (XmlElement imageE : spritesE.elementChildren()) {
			String id = getString(imageE, "id");			
			Rectangle uv = parseRect(imageE.getChild("uv"));			
			Point anchor = parsePoint(imageE.getChild("anchor"));
						
			CharaImageModel image = new CharaImageModel();
			image.id = id;
			image.anchor = anchor;
			image.imageBounds = uv;

			image.hitRects.clear();
			image.damageRects.clear();
			image.splashRects.clear();
			
			for (XmlElement rectE : imageE.getChild("hitRects").elementChildren()) {
				image.hitRects.add(parseRect(rectE));
			}
			//if (image.hitRects.isEmpty()) image.hitRects.add(new Rectangle());
			
			for (XmlElement rectE : imageE.getChild("damageRects").elementChildren()) {
				image.damageRects.add(parseDamageRect(rectE));
			}
			//if (image.damageRects.isEmpty()) image.damageRects.add(new DamageRect());

			for (XmlElement rectE : imageE.getChild("splashRects").elementChildren()) {
				image.splashRects.add(parseDamageRect(rectE));
			}
			//if (image.splashRects.isEmpty()) image.splashRects.add(new DamageRect());

			XmlElement colCirclesE = imageE.getChild("colCircles");
			if (colCirclesE != null) {
				for (XmlElement colCircleE : colCirclesE.elementChildren()) {
					image.colCircles.add(parseColCircle(colCircleE));
				}
			}
			//if (image.colCircles.isEmpty()) image.colCircles.add(new ColCircle());

			images.add(image);
		}

		return images;
	}
	
	public static DamageRect parseDamageRect(XmlElement e) {
		Rectangle r = parseRect(e);
		
		DamageRect dr = new DamageRect();
		dr.x = r.x; dr.y = r.y;
		dr.width = r.width; dr.height = r.height;
		dr.damage = Math.max(1, getInt(e, "damage", 1));
		dr.knockbackX = getInt(e, "knockbackX", 0);
		dr.knockbackY = getInt(e, "knockbackY", 0);
		return dr;
	}
	public static Rectangle parseRect(XmlElement e) {
		Rectangle r = new Rectangle();
		try {
			r.x = getInt(e, "x", 0);
			r.y = getInt(e, "y", 0);
			r.width = getInt(e, "width", 0);
			r.height = getInt(e, "height", 0);
		} catch (RuntimeException re) {
			Log.error(re);
		}
		return r;
	}
	public static Point parsePoint(XmlElement e) {
		Point p = new Point(0, 0);
		try {
			p.x = getInt(e, "x", 0);
			p.y = getInt(e, "y", 0);
		} catch (RuntimeException re) {
			Log.error(re);
		}
		return p;
	}
	public static ColCircle parseColCircle(XmlElement e) {
		ColCircle c = new ColCircle();
		c.x = getInt(e, "x", 0);
		c.y = getInt(e, "y", 0);
		c.setRadius(getInt(e, "radius", 0));
		return c;
	}

	public static XmlElement save(String path, Rectangle levelRect, Collection<CharaImageModel> charaImages) {
		XmlElement rootE = new XmlElement("charaImages");
		rootE.addAttribute("version", "1.0.0");
		
		rootE.addChild("imagePath", path);		
		saveRect(rootE, "levelHitbox", levelRect);
		
		XmlElement spritesE = rootE.addChild("images");
		for (CharaImageModel image : charaImages) {
			spritesE.addChild(image.save());
		}
		
		return rootE;
	}
	
	public static XmlElement saveRect(XmlElement parentE, String childName, Rectangle rect) {
		XmlElement e = parentE.addChild(childName);
		e.addChild("x", rect.x);
		e.addChild("y", rect.y);
		e.addChild("width", rect.width);
		e.addChild("height", rect.height);
		return e;
	}
	public static XmlElement saveDamageRect(XmlElement parentE, String childName, DamageRect rect) {
		XmlElement e = saveRect(parentE, childName, rect);
		e.addChild("damage", rect.damage);
		e.addChild("knockbackX", rect.knockbackX);
		e.addChild("knockbackY", rect.knockbackY);
		return e;
	}
	public static XmlElement saveColCircle(XmlElement parentE, String childName, ColCircle c) {
		XmlElement e = parentE.addChild(childName);
		e.addChild("x", c.x);
		e.addChild("y", c.y);
		e.addChild("radius", c.getRadius());
		return e;
	}
	
	//Getters
	public String getImagePath() { return imagePath; }
	public Rectangle getLevelRect() { return levelRect; }
	
	//Setters
	
}
